package edu.ynu.se.xiecheng.achitectureclass.service;

import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;

@Service
public class Ys7Service {

    private static final String GET_TOKEN_URL = "http://42.193.14.241:7000/ysapi/subAccount/getToken";
    private static final String ACCOUNT_ID = "1ca7f0ab24ba41b291346347ec30140e";
    private static final String CAPTURE_URL = "https://open.ys7.com/api/lapp/device/capture";

    // 使用 volatile 确保多线程环境下的可见性
    private volatile String accessToken;
    private volatile Long accessTokenExpiresAt;

    private final RestTemplate restTemplate;

    @Autowired
    public Ys7Service(RestTemplateBuilder builder) {
        this.restTemplate = builder.build();
        // 添加 FormHttpMessageConverter 支持 x-www-form-urlencoded
        this.restTemplate.getMessageConverters().add(new FormHttpMessageConverter());
        this.restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
        this.restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
    }
    /**
     * 获取 accessToken（带缓存和线程安全）
     */
    public String getToken() {
        // 检查 Token 是否已过期
        if (accessToken == null || System.currentTimeMillis() >= accessTokenExpiresAt) {
            synchronized (this) {
                // 双重检查锁，避免多个线程同时刷新 Token
                if (accessToken == null || System.currentTimeMillis() >= accessTokenExpiresAt) {
                    refreshAccessToken();
                }
            }
        }
        return accessToken;
    }

    /**
     * 刷新 accessToken
     */
    private void refreshAccessToken() {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        Map<String, String> requestBody = new HashMap<>();
        requestBody.put("accountId", ACCOUNT_ID);

        HttpEntity<Map<String, String>> request = new HttpEntity<>(requestBody, headers);

        ResponseEntity<CaTokenResponse> response = restTemplate.postForEntity(GET_TOKEN_URL, request, CaTokenResponse.class);

        if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
            CaTokenResponse tokenResponse = response.getBody();
            accessToken = tokenResponse.getData().getAccessToken();
            accessTokenExpiresAt = tokenResponse.getData().getExpireTime();
            System.out.println("Refreshed YS7 accessToken: " + accessToken);
        } else {
            throw new RuntimeException("Failed to get YS7 access token.");
        }
    }

    /**
     * 抓拍照片
     */
    public String capturePhoto(String deviceSerial) {
        String accessToken = getToken();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
        requestBody.add("accessToken", accessToken);
        requestBody.add("deviceSerial", deviceSerial);
        requestBody.add("channelNo", "1");
        requestBody.add("quality", "1");

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(requestBody, headers);

        ResponseEntity<CaptureResponse> response = restTemplate.postForEntity(CAPTURE_URL, request, CaptureResponse.class);

        if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
            return response.getBody().getData().getPicUrl();
        } else {
            throw new RuntimeException("Failed to capture photo from YS7 camera.");
        }
    }
}